home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / ttxsame / TTXSame.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-09  |  12.0 KB  |  401 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. /***************************************************************************/
  7. /*  Copyright (c) 1992 Obvious Implementation Corp. All Rights Reserved.   */
  8. /*                     207 Livingstone Drive,                              */
  9. /*                     Cary N.C. 27513 - USA                               */
  10. /***************************************************************************/
  11. #include <stdio.h>
  12. #include <exec/types.h>
  13. #include <proto/exec.h>
  14. #include <proto/dos.h>
  15. #include <dos/dosextens.h>
  16. #include <strings.h>
  17. #include <stdlib.h>
  18. #include <lib/rexx.h>
  19. #include "TTXSame_Rev.h"
  20.  
  21. extern struct Library *RexxSysBase;
  22. extern struct DosLibrary *DOSBase;
  23.  
  24. struct SAVER {
  25.    struct SAVER *next;
  26.    char         *fname;
  27. };
  28.  
  29. char *RexxHostName = NULL;
  30.  
  31. #define MAX_FILENAME 1024
  32. char buf[MAX_FILENAME+1];
  33.  
  34. /***********************************************************************************
  35.  * Procedure: full_path
  36.  * Synopsis:  path = full_path(name)
  37.  * Purpose:   Constructs a fully expanded filename
  38.  *            Note, we can not assume that the file exists, so it will not be possible
  39.  *            to actually lock it.  We can assume that the directory it is part of
  40.  *            does exist.
  41.  ***********************************************************************************/
  42. char *full_path(char *name)
  43. {
  44.    BPTR lock;
  45.    __aligned struct FileInfoBlock fib;
  46.    char *tail, *p;
  47.    int pos;
  48.  
  49.    /* Step 1 - split out any directory information from the actual name */
  50.    p = strrchr(name, '/');
  51.    if (p == NULL) p = strrchr(name, ':');
  52.    if (p != NULL)
  53.    {
  54.       /* There was some directory information involved */
  55.       char c;
  56.       tail = strdup(p+1);
  57.       c = p[1];
  58.       p[1] = 0;
  59.       lock = Lock(name, SHARED_LOCK);
  60.       p[1] = c;
  61.    }
  62.    else
  63.    {
  64.       /* No directory information involved, just the name relative to the */
  65.       /* current directory                                                */
  66.       lock = Lock("", SHARED_LOCK);
  67.       tail = strdup(name);
  68.    }
  69.  
  70.    /* Step 2 - we have the lock on the directory and the tail part of the name */
  71.    /* We want to construct a fully qualified path for the directory.           */
  72.    /* If for some reason the lock on the directory returned 0, we want to just */
  73.    /* return the name they gave us to begin with.                              */
  74.    if (lock == 0)
  75.    {
  76.       free(tail);
  77.       return(strdup(name));
  78.    }
  79.  
  80.    /* Step 3 - Fully qualify the directory portion into the buffer */
  81.    if (DOSBase->dl_lib.lib_Version >= 36)
  82.    {
  83.       if (!NameFromLock(lock, buf, MAX_FILENAME))
  84.       {
  85.          /* Either the name is too long or there was something else wrong with */
  86.          /* the file name, just return what they gave us as a start            */
  87.          UnLock(lock);
  88.          free(tail);
  89.          return(strdup(name));
  90.       }
  91.       UnLock(lock);
  92.       pos = 0;
  93.    }
  94.    else
  95.    {
  96.       /* Running under 1.3, we have to do this the old fashion way */
  97.  
  98.       /* Just so we don't have to do any inserts/extra copies, we will work */
  99.       /* from the end of the buffer and insert as we go                     */
  100.       pos = MAX_FILENAME;
  101.       buf[--pos] = 0;
  102.       while(lock != 0)
  103.       {
  104.          BPTR parent;
  105.          int len;
  106.  
  107.          /* Examine the lock to get the name for it */
  108.          Examine(lock, &fib);
  109.  
  110.          /* Find the parent of this directory       */
  111.          parent = ParentDir(lock);
  112.          UnLock(lock);
  113.          lock = parent;
  114.  
  115.          len = strlen(fib.fib_FileName);
  116.          pos -= 1;
  117.  
  118.          if (len > pos)
  119.          {
  120.             /* oops, not enough room, just return the name they gave us */
  121.             UnLock(lock);
  122.             free(tail);
  123.             return(strdup(name));
  124.          }
  125.          buf[pos] = lock ? ':' : '/';
  126.          pos -= len;
  127.          memcpy(buf+pos, fib.fib_FileName, len);
  128.       }
  129.    }
  130.  
  131.    /* We have the path part in the buffer and the name part in the tail */
  132.    /* All that is left is to concatenate them together correctly        */
  133.    {
  134.       int len;
  135.  
  136.       /* Successful, the buf holds the path for the directory.  We will need   */
  137.       /* to add a / to the end if it doesn't end in a colon                    */
  138.       len = strlen(buf+pos);
  139.       if ((buf[pos+len-1] != ':') && (buf[pos+len-1] != '/'))
  140.       {
  141.          buf[pos+len++] = '/';
  142.          buf[pos+len] = 0;
  143.       }
  144.       name = malloc(len+strlen(tail)+1);
  145.       if (name != NULL)
  146.       {
  147.          strcpy(name, buf+pos);
  148.          strcpy(name+len, tail);
  149.       }
  150.    }
  151.    return(name);
  152. }
  153.  
  154. /***********************************************************************************
  155.  * Procedure: dottx
  156.  * Synopsis:  result = dottx(port, cmd);
  157.  * Purpose:   Sends a command to TurboText
  158.  ***********************************************************************************/
  159. char *dottx(char *port, char *cmd)
  160. {
  161.    char *res;
  162.    long ec;
  163.  
  164.    if (port == NULL) port = "TURBOTEXT";
  165.    PlaceRexxCommandDirect(NULL, port, cmd, &res, &ec);
  166.  
  167.    return(res);
  168. }
  169.  
  170. /***********************************************************************************
  171.  * Procedure: say
  172.  * Synopsis:  (void)say(msg);
  173.  * Purpose:   Displays the given message on the console
  174.  ***********************************************************************************/
  175. void say(char *msg)
  176. {
  177.    BPTR out;
  178.    out = Output();
  179.    if (out)
  180.    {
  181.       Write(out, msg, strlen(msg));
  182.       Write(out, "\n", 1);
  183.    }
  184. }
  185.  
  186. /***********************************************************************************
  187.  * Procedure: usage
  188.  * Synopsis:  (void)usage();
  189.  * Purpose:   Displays the command line usage message - does not return
  190.  ***********************************************************************************/
  191. void usage(void)
  192. {
  193.    say("FILE/M,MACRO/K,PROJECT/K" VERSTAG);
  194.    exit(20);
  195. }
  196.  
  197. /***********************************************************************************
  198.  * Procedure: mustmalloc
  199.  * Synopsis:  mem = mustmalloc(size);
  200.  * Purpose:   Allocates memory or Displays an outof memory message -
  201.  *            if there is not enough memory, it does not return
  202.  ***********************************************************************************/
  203. void *mustmalloc(int size)
  204. {
  205.    void *r;
  206.  
  207.    r = malloc(size);
  208.    if (r == NULL)
  209.    {
  210.       say("No Memory!\n");
  211.       exit(20);
  212.    }
  213.    return(r);
  214. }
  215.  
  216. /***********************************************************************************
  217.  * Procedure: main
  218.  * Synopsis:  rc = main(argc, argv);
  219.  * Purpose:   Main entry point
  220.  ***********************************************************************************/
  221. int main(int argc, char **argv)
  222. {
  223.    char *res;
  224.    int i;
  225.    char *macro;
  226.    char *project;
  227.    struct SAVER base, *nsaver;
  228.  
  229.    project = NULL;
  230.    macro   = NULL;
  231.  
  232.    if (RexxSysBase == NULL)
  233.    {
  234.       say("Unable to open rexxsyslib.library!");
  235.       exit(20);
  236.    }
  237.  
  238.    CreateDiceRexxPort(NULL, NULL);
  239.  
  240.    nsaver = &base;
  241.    base.next = NULL;
  242.  
  243.    if ((argc == 2) && (!strcmp(argv[1], "?"))) usage();
  244.  
  245.    /* Template for command: */
  246.    /* FILE/M,MACRO/S,PROJECT/S */
  247.    for (i = 1; i < argc; i++)
  248.    {
  249.       if (!stricmp(argv[i], "MACRO"))
  250.       {
  251.          if (++i >= argc) usage();
  252.          if (macro != NULL) usage();
  253.          macro = mustmalloc(strlen(argv[i]) + 16); /* ExecArexxMacro */
  254.          strcpy(macro, "ExecArexxMacro ");
  255.          strcat(macro, argv[i]);
  256.       }
  257.       else if (!stricmp(argv[i], "PROJECT"))
  258.       {
  259.          if (++i >= argc) usage();
  260.          project = argv[i];
  261.       }
  262.       else
  263.       {
  264.          if (!stricmp(argv[i], "FILE"))
  265.          {
  266.             if (++i >= argc) usage();
  267.          }
  268.          nsaver->next = mustmalloc(sizeof(struct SAVER));
  269.          nsaver = nsaver->next;
  270.          nsaver->fname = full_path(argv[i]);
  271.          nsaver->next  = NULL;
  272.       }
  273.    }
  274.  
  275.    /* We have parsed our parameters, now we need to load each of the files */
  276.    /* specified into the editor.  In the process we will have to check for */
  277.    /* Any files in the editor to ensure that they are not already loaded   */
  278.    while((nsaver = base.next) != NULL)
  279.    {
  280.       /* Send the command off to rexx to be processed */
  281.       /* We will wait here until it is complete       */
  282.       res = dottx(NULL, "GETDOCUMENTS");
  283.       if (res != NULL)
  284.       {
  285.          char *p, *t, *fname, *pname;
  286.          int len;
  287.          /* Now we need to go through and figure out all the files that are there */
  288.          fname = res;
  289.          pname = NULL;
  290.          while(*fname)
  291.          {
  292.             if (*fname != '"')
  293.             {
  294.                say("TURBOTEXT Sync Error");
  295.                return(20);
  296.             }
  297.             fname++;
  298.             t = fname;
  299.             len = strlen(t);
  300.             while ((len > 11) && memcmp(t, "\" TURBOTEXT", 11)) /* Bug with no parm */
  301.             {
  302.                char *s;
  303.                s = strchr(t+1, '"');
  304.                if (s == NULL) break;
  305.                len -= (s-t);
  306.                t = s;
  307.             }
  308.             /* At this point, t should be pointing at the " in the name */
  309.             *t = 0;
  310.             /* Now we want to get the portname for the file */
  311.             t += 2;
  312.             pname = t;
  313.             while(*t && (*t != ' ')) t++;
  314.             if (*t) *t++ = 0;
  315.  
  316.             p = dottx(pname, "GetFilePath");
  317.  
  318.             /* If this is the file that we are interested in, drop out of the */
  319.             /* loop and go to work on it in the file                          */
  320.             if ((p != NULL) && !stricmp(nsaver->fname, p))
  321.                break;
  322.  
  323.             /* Advance to let the next stuff work */
  324.             fname = t;
  325.             while(*fname == ' ') fname++;
  326.             pname = NULL;
  327.          }
  328.  
  329.          /* If we got a match, the port will tell us who to talk to */
  330.          if (pname == NULL)
  331.          {
  332.             char *ocmd;
  333.             ocmd = mustmalloc(strlen(nsaver->fname) + 15);  /* OPENDOC NAME */
  334.             strcpy(ocmd, "OPENDOC NAME ");
  335.             strcat(ocmd, nsaver->fname);
  336.             pname = dottx(NULL, ocmd);
  337.             free(ocmd);
  338.          }
  339.          else
  340.          {
  341.             char *p;
  342.             p = dottx(pname, "WINDOW2FRONT");
  343.             if (p != NULL) free(p);
  344.             p = dottx(pname, "SCREEN2FRONT");
  345.             if (p != NULL) free(p);
  346.          }
  347.          {
  348.             char *p;
  349.             p = dottx(pname, "ACTIVATEWINDOW");
  350.             if (p != NULL) free(p);
  351.          }
  352.  
  353.          /* We now have the document open, pname is the port to talk to */
  354.          if (project != NULL)
  355.          {
  356.             char *ocmd;
  357.             /* ExecARexxString call setclip(TTX_TURBOTEXT12,myport.1)   */
  358.             /* 123456789012345678901234567890123           4        5   */
  359.             ocmd = mustmalloc(strlen(project)+strlen(pname)+36);
  360.             strcpy(ocmd, "ExecARexxString call setclip(TTX_");
  361.             strcat(ocmd, pname);
  362.             strcat(ocmd, ",");
  363.             strcat(ocmd, project);
  364.             strcat(ocmd, ")");
  365.             p = dottx(pname, ocmd);
  366.             if (p != NULL) free(p);
  367.             free(ocmd);
  368.          }
  369.  
  370.          /* Next we want to issue the macro command to make it run */
  371.          if (macro != NULL)
  372.          {
  373.             char *p;
  374.             p = dottx(pname, macro);
  375.             if (p != NULL) free(p);
  376.          }
  377.          free(res);
  378.       }
  379.  
  380.       /* Take the entry off the list because we have already processed it */
  381.       base.next = nsaver->next;
  382.       free(nsaver->fname);
  383.       free(nsaver);
  384.    }
  385.    return(0);
  386. }
  387.  
  388. /***********************************************************************************
  389.  * Procedure: DoRexxCommand
  390.  * Synopsis:  rc = DoRexxCommand(msg, port, arg, pres)
  391.  * Purpose:   Handling executing a rexx command
  392.  ***********************************************************************************/
  393. long DoRexxCommand(void *msg,              /* RexxMsg structure if we need it      */
  394.                    struct MsgPort *port,   /* MsgPort structure if we need it      */
  395.                    char *arg0,             /* arg0                                 */
  396.                    char **pres             /* where to put our result if rc==0     */
  397.                   )
  398. {
  399.    return(0);
  400. }
  401.